<?php
/**
 * @package LaravelBoot
 *
 * @internal
 *
 * @author mawenpei
 * @date 2018/7/24 18:58
 * @version
 */
namespace Modules\Wechat\Logics;

use Modules\Wechat\Exceptions\WechatDecryptException;
use GuzzleHttp\Client;

class WechatLogic
{
    const DOMAIN = 'https://api.weixin.qq.com';

    const SESSION_URL = self::DOMAIN . '/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code';

    const TOKEN_URL = self::DOMAIN . '/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}';

    public static function codeToSession($code,$appId,$secret)
    {
        $client = new Client();
        $url = str_replace(['{appid}','{secret}','{code}'],[$appId,$secret,$code],self::SESSION_URL);
        $response = $client->request('GET',$url);
        if($response->getStatusCode()==200){
            $data = json_decode($response->getBody()->getContents(),true);
            if(isset($data['openid'])){
                return $data;
            }
        }
        return [];
    }

    /**
     * 检验数据的真实性，并且获取解密后的明文.
     * @param $encryptedData string 加密的用户数据
     * @param $iv string 与用户数据一同返回的初始向量
     * @param $appId
     * @param $sessionKey
     *
     * @return bool 成功0，失败返回对应的错误码
     */
    public static function decryptData($encryptedData, $iv,$appId,$sessionKey)
    {
        if (strlen($sessionKey) != 24) {
            throw new WechatDecryptException('session_key is error');
        }
        $aesKey = base64_decode($sessionKey);

        if (strlen($iv) != 24) {
            throw new WechatDecryptException('iv is error');
        }
        $aesIV = base64_decode($iv);

        $aesCipher = base64_decode($encryptedData);

        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

        $dataObj = json_decode($result,true);
        if ($dataObj == false) {
            throw new WechatDecryptException('decrypt fail');
        }
        if ($dataObj['watermark']['appid'] != $appId) {
            throw new WechatDecryptException('watermark check fail');
        }
        return $dataObj;
    }

    /**
     *
     * @param $appId
     * @param $secret
     * @return array|mixed
     */
    public static function getAccessToken($appId,$secret)
    {
        $client = new Client();
        $url = str_replace(['{appid}','{secret}'],[$appId,$secret],self::TOKEN_URL);
        $response = $client->request('GET',$url);
        if($response->getStatusCode()==200){
            $data = json_decode($response->getBody()->getContents(),true);
            if(isset($data['access_token'])){
                return $data;
            }
        }
        return [];
    }


}